<template>
  <el-card>
    <div style="margin-bottom: 10px">
      <el-select v-model="metric" @change="onMetricChange" placeholder="选择指标" style="width: 180px">
        <el-option label="平均播放量" value="avgView" />
        <el-option label="平均点赞数" value="avgLike" />
        <el-option label="平均投币数" value="avgCoin" />
        <el-option label="平均收藏数" value="avgFavorite" />
        <el-option label="平均分享数" value="avgShare" />
        <el-option label="平均弹幕数" value="avgDanmuku" />
        <el-option label="平均评论数" value="avgReply" />
      </el-select>
    </div>

    <div ref="chart" style="height: 600px"></div>
  </el-card>
</template>

<script setup>
import { onMounted, computed, ref } from 'vue'
import * as echarts from 'echarts'
import { useApi } from '@/composables/useApi'
import { toPercent } from '@/utils/formatting'

const http = useApi()

const chart = ref(null)
const isSub = ref(false)
const metric = ref('avgView') // 默认指标

const legendData = computed(() => {
  const label = metricLabel[metric.value]
  const rateLabel = metricRateLabel[metric.value]
  const showRate = metric.value !== 'avgView'
  const arr = [label] // 柱状图系列一定显示
  if (showRate) arr.push(rateLabel) // 折线图系列可选
  return arr
})
const metricLabel = {
  avgView: '平均播放量',
  avgLike: '平均点赞数',
  avgCoin: '平均投币数',
  avgFavorite: '平均收藏数',
  avgShare: '平均分享数',
  avgDanmuku: '平均弹幕数',
  avgReply: '平均评论数',
}
const metricRateLabel = {
  avgLike: '点赞率',
  avgCoin: '投币率',
  avgFavorite: '收藏率',
  avgShare: '分享率',
  avgDanmuku: '弹幕播放比',
  avgReply: '评论播放比',
}
const metricApi = {
  avgView: '/video/getView',
  avgLike: '/video/getLike',
  avgCoin: '/video/getCoin',
  avgFavorite: '/video/getFavorite',
  avgShare: '/video/getShare',
  avgDanmuku: '/video/getDanmuku',
  avgReply: '/video/getReply',
}

let myChart = null
let topData = []
let viewData = []
let parentName = ''

function renderTop() {
  isSub.value = false
  if (!myChart) myChart = echarts.init(chart.value)

  const label = metricLabel[metric.value]
  const rateLabel = metricRateLabel[metric.value]
  const showRate = metric.value !== 'avgView'
  const showPercent = ['avgLike', 'avgCoin', 'avgFavorite'].includes(metric.value)
  const formatter2 = (x) => (x * 1e4).toFixed(1) + '/万播放'

  const option = {
    backgroundColor: '#f5f5f5',
    title: { text: `B站各分区${label}`, left: 'center' },
    tooltip: { trigger: 'axis' },
    legend: {
      data: legendData.value,
      top: 10,
      right: 10,
    },
    xAxis: {
      type: 'category',
      data: topData.map((d) => d.name),
      axisLabel: { rotate: 0, color: '#333' },
    },
    yAxis: [
      { type: 'value', name: label },
      {
        type: 'value',
        name: rateLabel,
        axisLabel: { formatter: showPercent ? toPercent : formatter2 },
        show: showRate,
      },
    ],
    series: [
      {
        name: label,
        type: 'bar',
        data: topData.map((d) => d.avg),
        itemStyle: { color: '#7385de', borderRadius: [4, 4, 0, 0] },
      },
      {
        name: rateLabel,
        type: 'line',
        yAxisIndex: 1,
        data: showRate ? topData.map((d, i) => d.avg / viewData[i].avg) : [],
        itemStyle: { color: '#44bb44' },
        lineStyle: { width: 2 },
        tooltip: { valueFormatter: showPercent ? toPercent : formatter2 },
      },
    ],
    graphic: [
      {
        type: 'text',
        left: '4%',
        bottom: '4%',
        style: {
          text: `💡 点击柱子查看子分区${label}`,
          fontSize: 14,
          fill: '#666',
        },
      },
    ],
  }
  myChart.setOption(option)

  myChart.off('click')
  myChart.on('click', (params) => {
    const item = topData.find((d) => d.name === params.name)
    if (item?.subZones?.length) renderSub(item.subZones, item.name)
  })
}

function renderSub(subZones, pname) {
  isSub.value = true
  parentName = pname
  const label = metricLabel[metric.value]
  const option = {
    title: { text: `${pname} - 子分区${label}`, left: 'center' },
    xAxis: { data: subZones.map((s) => s.name) },
    yAxis: [{ type: 'value', name: label }],
    series: [
      {
        type: 'bar',
        name: label,
        data: subZones.map((s) => s.avg),
        itemStyle: { color: '#91cc75', borderRadius: [4, 4, 0, 0] },
      },
    ],
    graphic: [
      {
        type: 'text',
        left: '4%',
        bottom: '4%',
        style: {
          text: `💡 点击柱子返回一级`,
          fontSize: 14,
          fill: '#666',
        },
      },
    ],
  }

  myChart.setOption(option, { replaceMerge: ['yAxis', 'series'] })
  myChart.off('click')
  myChart.on('click', () => backToTop())
}

function backToTop() {
  renderTop()
}

async function loadData() {
  const api = metricApi[metric.value]
  const res = await http.get(api)
  topData = res.data
  if (metric.value === 'avgView') viewData = res.data
  console.log('后端数据', res.data)
  renderTop()
}

function onMetricChange() {
  loadData()
}

onMounted(() => {
  loadData()
  window.addEventListener('resize', () => myChart?.resize())
})
</script>
